section .data							; initializing data 

; setting up the Multiboot header (see GRUB docs)
MODULEALIGN equ  1b						; align loaded modules on page boundaries
MEMINFO     equ  10b	                    ; provide memory map
FLAGS       equ  MODULEALIGN | MEMINFO  ; this is the Multiboot 'flag' field
MAGIC       equ    0x1BADB002           ; 'magic number' lets bootloader find the header
CHECKSUM    equ -(MAGIC + FLAGS)        ; checksum required

STACKSIZE equ 0x4000          			; kernel stack size: 16k.

section .bss							; declaring variables

align 32
stack:	resb STACKSIZE     				; reserve 16k stack on a quadword boundary

extern start             				; main method (extern)
				
extern start_ctors, end_ctors			; extern variables 
extern start_dtors, end_dtors 			;(they come from linker.ld)


section .text							; the code properly

global bootstrap						; code entry point           

align 4
MultiBootHeader:
   		dd MAGIC
   		dd FLAGS
		dd CHECKSUM

bootstrap:
  		mov esp, stack+STACKSIZE    ; set up the stack
		push ebx			        ; pass Multiboot info structure

static_ctors_loop:					; loop to call static constructors
		mov ebx, start_ctors
		jmp .test
.body:
		call [ebx]
		add ebx,4
.test:
		cmp ebx, end_ctors
		jb .body
		
		call start                  ; call kernel proper

static_destructors_loop:			; loop to call static deconstructors
		mov ebx, start_dtors
		jmp .test
.body:
		call [ebx]
		add ebx,4
.test:
		cmp ebx, end_dtors
		jb .body

		hlt                         ; halt machine should kernel return
